package com.open.cloud.common.bean;

import com.open.cloud.common.code.CodeMsg;
import com.open.cloud.common.code.CodeMsgType;
import com.open.cloud.common.code.CodeMsgs;

/**
 *
 * 业务处理结果。添加了成功和失败的标记字段，方便跨层处理结果。
 *
 * @author kong
 * @date 2021/2/13
 * blog: http://blog.kongyin.ltd
 */
public class ServiceResult<T> {
    /**
     * 结果状态
     */
    private boolean success;
    /**
     * 错误代码
     */
    private String code;
    /**
     * 错误消息
     */
    private String message;
    /**
     * 错误详情
     */
    private String detail;
    /**
     * 结果数据
     */
    private T data;

    private ServiceResult() {
    }

    /**
     * 使用构造器的构造方法
     *
     * @param builder 构造器
     */
    private ServiceResult(Builder<T> builder) {
        CodeMsg codeMsg = builder.codeMsg;
        String code = codeMsg.getCode();
        if (code == null || !code.startsWith(CodeMsgType.BIZ_FAIL.getCode())) {
            throw new IllegalArgumentException("业务结果代码必须以[" + CodeMsgType.BIZ_FAIL.getCode() + "]开头");
        }
        this.success = builder.success;
        this.code = code;
        this.message = codeMsg.getMessage();
        this.detail = builder.detail;
        this.data = builder.data;
    }

    /**
     * 获取对象构造器
     *
     * @param <T> 构造对象中数据对象的类型
     * @return
     */
    private static <T> Builder<T> builder() {
        return new Builder<T>();
    }

    /**
     * 构造器对象
     *
     * @param <T>
     */
    public static class Builder<T> {
        private boolean success;
        private CodeMsg codeMsg;
        private String detail;
        private T data;

        /**
         * 设置结果
         *
         * @param success 成功：true; 失败：false。
         * @return 构造器
         */
        public Builder success(boolean success) {
            this.success = success;
            return this;
        }

        /**
         * 设置消息代码
         *
         * @param codeMsg 消息代码对象
         * @return 构造器
         */
        public Builder codeMsg(CodeMsg codeMsg) {
            this.codeMsg = codeMsg;
            return this;
        }

        /**
         * 设置消息详细描述
         *
         * @param detail 消息详细描述
         * @return 构造器
         */
        public Builder detail(String detail) {
            this.detail = detail;
            return this;
        }

        /**
         * 设置数据内容
         *
         * @param data 数据对象
         * @return 构造器
         */
        public Builder data(T data) {
            this.data = data;
            return this;
        }

        /**
         * 创建ServiceResult对象
         *
         * @return ServiceResult对象
         */
        public ServiceResult<T> build() {
            return new ServiceResult<>(this);
        }
    }

    /**
     * 成功结果
     *
     * @param <T> 结果数据对象类型
     * @return
     */
    public static <T> ServiceResult<T> success() {
        return new Builder<T>().success(true).codeMsg(CodeMsgs.SERVICE_BASE_SUCCESS).build();
    }

    /**
     * 成功结果。可以指定结果详细描述
     *
     * @param detail 结果详细描述
     * @param <T>    结果数据对象类型
     * @return
     */
    public static <T> ServiceResult<T> success(String detail) {
        return new Builder<T>().success(true).codeMsg(CodeMsgs.SERVICE_BASE_SUCCESS).detail(detail).build();
    }

    /**
     * 成功结果。可以指定结果详细描述 和 数据
     *
     * @param detail 结果详细描述
     * @param data   结果数据
     * @param <T>    结果数据对象类型
     * @return
     */
    public static <T> ServiceResult<T> success(String detail, T data) {
        return new Builder<T>().success(true).codeMsg(CodeMsgs.SERVICE_BASE_SUCCESS).detail(detail).data(data).build();
    }

    /**
     * 成功结果。可以指定结果数据
     *
     * @param data 结果数据
     * @param <T>  结果数据对象类型
     * @return 结果
     */
    public static <T> ServiceResult<T> success(T data) {
        return new Builder<T>().success(true).codeMsg(CodeMsgs.SERVICE_BASE_SUCCESS).data(data).build();
    }

    /**
     * 成功结果。可以指定结果代码、详细描述和数据
     *
     * @param codeMsg 结果代码
     * @param detail  详细描述
     * @param data    数据
     * @param <T>     结果数据对象类型
     * @return
     */
    public static <T> ServiceResult<T> success(CodeMsg codeMsg, String detail, T data) {
        return new Builder<T>().success(true).codeMsg(codeMsg).detail(detail).data(data).build();
    }

    /**
     * 成功结果
     *
     * @param <T> 结果数据对象类型
     * @return
     */
    public static <T> ServiceResult<T> fail() {
        return new Builder<T>().success(false).codeMsg(CodeMsgs.SERVICE_BASE_ERROR).build();
    }

    /**
     * 成功结果。可以指定结果详细描述
     *
     * @param detail 结果详细描述
     * @param <T>    结果数据对象类型
     * @return
     */
    public static <T> ServiceResult<T> fail(String detail) {
        return new Builder<T>().success(false).codeMsg(CodeMsgs.SERVICE_BASE_ERROR).detail(detail).build();
    }

    /**
     * 失败结果。可以指定结果详细描述 和 数据
     *
     * @param detail 结果详细描述
     * @param data   结果数据
     * @param <T>    结果数据对象类型
     * @return
     */
    public static <T> ServiceResult<T> fail(String detail, T data) {
        return new Builder<T>().success(false).codeMsg(CodeMsgs.SERVICE_BASE_ERROR).detail(detail).data(data).build();
    }

    /**
     * 失败结果。可以指定结果代码、详细描述和数据
     *
     * @param codeMsg 结果代码
     * @param detail  详细描述
     * @param data    数据
     * @param <T>     结果数据对象类型
     * @return
     */
    public static <T> ServiceResult<T> fail(CodeMsg codeMsg, String detail, T data) {
        return new Builder<T>().success(false).codeMsg(codeMsg).detail(detail).data(data).build();
    }

    public boolean isSuccess() {
        return success;
    }

    public String getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

    public String getDetail() {
        return detail;
    }

    public T getData() {
        return data;
    }
}
